﻿using System;
using System.Windows;
using System.Windows.Data;
using System.Globalization;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using Candy.Web.Data;
using Candy.ViewModel;
using System.Collections.ObjectModel;
using System.Collections.Generic;
using Candy.Model;
using System.Linq;
using System.Collections;

namespace Candy.Infrastructure
{

    public class NegateConverter : IValueConverter
    {
        public object Convert(
            object value,
            Type targetType,
            object parameter,
            CultureInfo culture)
        {
            bool val = (bool)value;
            return !val;
        }

        public object ConvertBack(
            object value,
            Type targetType,
            object parameter,
            CultureInfo culture)
        {
            bool val = (bool)value;
            return !val;
        }
    }


    /// <summary>   
    /// A type converter for visibility and boolean values.   
    /// </summary>   
    public class VisibilityConverter : IValueConverter
    {
        public object Convert(
            object value,
            Type targetType,
            object parameter,
            CultureInfo culture)
        {
            if (value is bool)
            {
                bool negate = false;
                if (parameter != null && parameter.ToString().ToLower().Trim() == "negate")
                    negate = true;

                bool visibility = (bool)value;
                if (negate)
                    return visibility ? Visibility.Collapsed : Visibility.Visible;
                else
                    return visibility ? Visibility.Visible : Visibility.Collapsed;
            }
            else
                return Visibility.Collapsed;
        }

        public object ConvertBack(
            object value,
            Type targetType,
            object parameter,
            CultureInfo culture)
        {
            Visibility visibility = (Visibility)value;
            return (visibility == Visibility.Visible);
        }
    }


    public class FontWeightConverter : IValueConverter
    {
        public object Convert(
            object value,
            Type targetType,
            object parameter,
            CultureInfo culture)
        {
            bool fWeight = (bool)value;
            return fWeight ? FontWeights.Bold : FontWeights.Normal;
        }

        public object ConvertBack(
            object value,
            Type targetType,
            object parameter,
            CultureInfo culture)
        {
            FontWeight fWeight = (FontWeight)value;
            return (fWeight == FontWeights.Bold);
        }
    }

    public class Gene2ColorConverter : IValueConverter
    {
        public object Convert(
            object value,
            Type targetType,
            object parameter,
            CultureInfo culture)
        {

            //   return "000000".ToBrush();
            GeneDto gene = value as GeneDto;
            if (gene == null)
                return "#000000".ToBrush();
            else
            {
                //LinearGradientBrush gb = new LinearGradientBrush();
                //gb.StartPoint = new Point(0, 0);
                //gb.EndPoint = new Point(1, 0);
                //GradientStop gs1 = new GradientStop();
                //gs1.Color = "#0026FF".ToColor();
                //GradientStop gs2 = new GradientStop();
                //gs2.Color = "#0026FF".ToColor();
                //gs2.Offset = 0.4999;
                //GradientStop gs3 = new GradientStop();
                //gs3.Color = "#00A813".ToColor();
                //gs3.Offset = 0.5;
                //gb.GradientStops.Add(gs1);
                //gb.GradientStops.Add(gs2);
                //gb.GradientStops.Add(gs3);

                if (gene.EntryType == GeneEntryType.bait && gene.IsCandidate) //bait and candidate
                    return App.Current.Resources["IconGreen"]; //"#00A813".ToBrush();
                if (gene.EntryType == GeneEntryType.bait && !gene.IsCandidate) //bait
                    return App.Current.Resources["IconBlue"];
                if (gene.EntryType != GeneEntryType.bait && gene.IsCandidate) // candidate
                    return App.Current.Resources["IconGreen"];
                return App.Current.Resources["IconRed"]; //secondaryBait
            }

        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

    public class FamilyTypeToColorConverter : IValueConverter
    {
        public object Convert(
            object value,
            Type targetType,
            object parameter,
            CultureInfo culture)
        {

            FamilyType ft;
            if (value is FamilyType)
                ft = (FamilyType)value;
            else
                return null;

            if (ft == FamilyType.family)
                return App.Current.Resources["IconGreen"];
            if (ft == FamilyType.group)
                return App.Current.Resources["IconBlue"];
            if (ft == FamilyType.superfamily)
                return App.Current.Resources["IconRed"];
            return null;

        }

        public object ConvertBack(
            object value,
            Type targetType,
            object parameter,
            CultureInfo culture)
        {
            return null;
        }
    }

    public class FamilyTypeToSymbolConverter : IValueConverter
    {
        public object Convert(
            object value,
            Type targetType,
            object parameter,
            CultureInfo culture)
        {
            FamilyType ft;
            if (value is FamilyType)
                ft = (FamilyType)value;
            else
                return null;

            if (ft == FamilyType.family)
                return "F";
            if (ft == FamilyType.group)
                return "G";
            if (ft == FamilyType.superfamily)
                return "SF";
            return null;


        }

        public object ConvertBack(
            object value,
            Type targetType,
            object parameter,
            CultureInfo culture)
        {
            return null;
        }
    }


    public class Gene2TypeLabelConverter : IValueConverter
    {
        public object Convert(
            object value,
            Type targetType,
            object parameter,
            CultureInfo culture)
        {
            GeneDto gene = value as GeneDto;
            if (gene == null)
                return "";
            else
            {
                if (gene.EntryType == GeneEntryType.bait && gene.IsCandidate) //bait and candidate
                    return "BC";
                if (gene.EntryType == GeneEntryType.bait && !gene.IsCandidate) //bait
                    return "B";
                if (gene.EntryType != GeneEntryType.bait && gene.IsCandidate) // candidate
                    return "C";
                return "SB"; //secondaryBait
            }

        }

        public object ConvertBack(
            object value,
            Type targetType,
            object parameter,
            CultureInfo culture)
        {
            return null;
        }
    }



    public class StateImageConverter : IValueConverter
    {
        public object Convert(
            object value,
            Type targetType,
            object parameter,
            CultureInfo culture)
        {
            string state = (string)value;
            switch (state)
            {
                case "Error":
                    {
                        return new BitmapImage(new Uri("Images/Symbol-Error_25x25.png", UriKind.Relative));
                    }
                case "Warning":
                    {
                        return new BitmapImage(new Uri("Images/Symbol-Exclamation_25x25.png", UriKind.Relative));
                    }
                case "Success":
                    {
                        return new BitmapImage(new Uri("Images/Symbol-Check_25x25.png", UriKind.Relative));
                    }
                default:
                    return new BitmapImage(new Uri("Images/Symbol-Help_25x25.png", UriKind.Relative));
            }

        }

        public object ConvertBack(
            object value,
            Type targetType,
            object parameter,
            CultureInfo culture)
        {
            return "";
        }
    }

    public class SrRatingConverter : IValueConverter
    {
        public object Convert(
            object value,
            Type targetType,
            object parameter,
            CultureInfo culture)
        {
            int val = (int)value;

            double ret = (double)(1d / 5d) * val;
            return Math.Round(ret, 1);
        }

        public object ConvertBack(
            object value,
            Type targetType,
            object parameter,
            CultureInfo culture)
        {
            double val = (double)value;

            int ret = (int)Math.Ceiling(val * 5);
            return ret;
        }
    }

    public class JobStatusVisibilityConverter : IValueConverter
    {

        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            //BlastJobDto s;

            //var t =  value.GetType();


            if (value is Candy.Web.Data.RequestStatus)
            {

                //PENDING = 0,
                //REQUEST_FAILED = 1,
                //ERROR = 2,
                //RUNNING = 3,
                //NOT_FOUND = 4,
                //DONE = 5,
                //UNKNOWN = 6,
                //RESULTS = 7,
                if (parameter is string && !string.IsNullOrEmpty((string)parameter))
                {
                    Candy.Web.Data.RequestStatus p = (Candy.Web.Data.RequestStatus)Enum.Parse(typeof(Candy.Web.Data.RequestStatus), (string)parameter, true);
                    Candy.Web.Data.RequestStatus stat = (Candy.Web.Data.RequestStatus)value;
                    switch (stat)
                    {
                        case Candy.Web.Data.RequestStatus.PENDING:
                            {
                                if (p == Candy.Web.Data.RequestStatus.PENDING)
                                    return Visibility.Visible;
                                else
                                    return Visibility.Collapsed;
                            }
                        case Candy.Web.Data.RequestStatus.REQUEST_FAILED:
                            goto case Candy.Web.Data.RequestStatus.ERROR;
                        case Candy.Web.Data.RequestStatus.ERROR:
                            {
                                if (p == Candy.Web.Data.RequestStatus.ERROR)
                                    return Visibility.Visible;
                                else
                                    return Visibility.Collapsed;
                            }
                        case Candy.Web.Data.RequestStatus.RUNNING:
                            {
                                if (p == Candy.Web.Data.RequestStatus.RUNNING)
                                    return Visibility.Visible;
                                else
                                    return Visibility.Collapsed;
                            }
                        case Candy.Web.Data.RequestStatus.NOT_FOUND:
                            goto case Candy.Web.Data.RequestStatus.ERROR;
                        case Candy.Web.Data.RequestStatus.DONE:
                            {
                                if (p == Candy.Web.Data.RequestStatus.DONE)
                                    return Visibility.Visible;
                                else
                                    return Visibility.Collapsed;
                            }
                        case Candy.Web.Data.RequestStatus.UNKNOWN:
                            goto case Candy.Web.Data.RequestStatus.ERROR;
                        case Candy.Web.Data.RequestStatus.RESULTS:
                            goto case Candy.Web.Data.RequestStatus.DONE;
                        default:
                            return Visibility.Collapsed;
                    }

                }
                else
                {
                    return Visibility.Collapsed;
                }

            }
            else
            {
                return Visibility.Collapsed;
            }
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

    public class JobDefinitionConverter : IValueConverter
    {

        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value is FamilyDto)
            {
                FamilyDto gf = (FamilyDto)value;
                BlastJobDefinitionDto dto = new BlastJobDefinitionDto()
                {
                    FamilyId = gf.Id,
                    FamilyName = gf.Name,
                    Task = BlastTask.blast_fishing_dbs
                };
                return dto;

            }
            else if (value is ObservableCollection<GeneEditViewModel>)
            {
                ObservableCollection<GeneEditViewModel> genes = (ObservableCollection<GeneEditViewModel>)value;

                List<BlastJobDefinitionDto> ret = new List<BlastJobDefinitionDto>();
                foreach (var g in genes)
                {
                    ret.Add(

                     new BlastJobDefinitionDto()
                               {
                                   GeneId = g.Entity.Id,
                                   GeneName = g.Entity.Name,
                                   SecondaryBaitDatabase = "uniprotkb_swissprot",
                                   FamilyId = g.Entity.FamilyId,
                                   FamilyName = g.Entity.Name,
                                   Task = BlastTask.find_ortholog_genes
                               }
                    );
                }

                return ret;

            }
            else
                return value;
        }



        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

    public class GeneListConverter : IValueConverter
    {

        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            //if (value is FamilyDto)
            //{
            //    FamilyDto gf = (FamilyDto)value;
            //    gf.
            //    BlastJobDefinitionDto dto = new BlastJobDefinitionDto()
            //    {
            //        FamilyId = gf.Id,
            //        FamilyName = gf.Name,
            //        Task = BlastTask.blast_fishing_dbs
            //    };
            //    return dto;

            //}
            //else
            if (value is IEnumerable<GeneEditViewModel>)
            {
                IEnumerable<GeneEditViewModel> genes = (IEnumerable<GeneEditViewModel>)value;
                return genes.Select(x => x.Entity).ToList();
            }
            else
                return value;
        }



        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }


    public class FamilyType2BoolConverter : IValueConverter
    {
        public object Convert(
            object value,
            Type targetType,
            object parameter,
            CultureInfo culture)
        {
            if (value is FamilyType && parameter != null)
            {
                FamilyType ft = (FamilyType)value;
                return ft.ToString().ToLower() == parameter.ToString().Trim().ToLower();
            }
            else
            {
                return false;
            }
        }

        public object ConvertBack(
            object value,
            Type targetType,
            object parameter,
            CultureInfo culture)
        {
            if (value is bool && parameter != null)
            {
                bool b = (bool)value;
                if (b)
                {
                    FamilyType ft = (FamilyType)Enum.Parse(typeof(FamilyType), parameter.ToString(), true);
                    return ft;
                }
                else
                {
                    return null;// FamilyType.Family;
                }
            }
            else
            {
                return FamilyType.family;
            }
        }
    }

    public class AnnotationType2IconConverter : IValueConverter
    {
        public object Convert(
            object value,
            Type targetType,
            object parameter,
            CultureInfo culture)
        {
            if (value is AnnotationType)
            {
                AnnotationType ft = (AnnotationType)value;
                switch (ft)
                {
                    case AnnotationType.Description:
                        return "Images/Icons/Text.png";
                    case AnnotationType.MolecularFunction:
                        return "Images/Icons/Molecule.png";
                    case AnnotationType.Reference:
                        return "Images/Icons/Web.png";
                    case AnnotationType.Synonym:
                        return "Images/Icons/Text.png";
                    case AnnotationType.Tag:
                        return "Images/Icons/Tag.png";
                    case AnnotationType.Pathway:
                        return "Images/Icons/Node.png";
                    case AnnotationType.History:
                        return "Images/Icons/Text.png";
                    default:
                        return null;
                }
            }
            else
            {
                return null;
            }
        }

        public object ConvertBack(
            object value,
            Type targetType,
            object parameter,
            CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

    public class ListNullOrEmptyVisibiltyConverter : IValueConverter
    {
        public object Convert(
            object value,
            Type targetType,
            object parameter,
            CultureInfo culture)
        {
            bool isVisible = true;
            if (value is IList)
            {
                IList list = (IList)value;
                isVisible = list.Count > 0;
            }
            else if (value == null)
            {
                isVisible = false;
            }
            else
            {
                return Visibility.Collapsed;
            }

            if (parameter != null && parameter.ToString().ToLower() == "negate")
            {
                isVisible = !isVisible;
            }
            return isVisible ? Visibility.Visible : Visibility.Collapsed;
        }

        public object ConvertBack(
            object value,
            Type targetType,
            object parameter,
            CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }



}
